home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / BitSet.h < prev    next >
C/C++ Source or Header  |  1994-05-11  |  9KB  |  375 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988 Free Software Foundation
  4.     written by Doug Lea (dl@rocky.oswego.edu)
  5.  
  6. This file is part of the GNU C++ Library.  This library is free
  7. software; you can redistribute it and/or modify it under the terms of
  8. the GNU Library General Public License as published by the Free
  9. Software Foundation; either version 2 of the License, or (at your
  10. option) any later version.  This library is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE.  See the GNU Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #ifndef _BitSet_h
  20. #ifdef __GNUG__
  21. #pragma interface
  22. #endif
  23.  
  24. #define _BitSet_h 1
  25.  
  26. #include <iostream.h>
  27. #include <limits.h>
  28.  
  29. #define BITSETBITS  (sizeof(short) * CHAR_BIT)
  30.  
  31. struct BitSetRep
  32. {
  33.   unsigned short  len;          // number of shorts in s
  34.   unsigned short  sz;           // allocated slots
  35.   unsigned short  virt;         // virtual 0 or 1
  36.   unsigned short  s[1];         // bits start here
  37. };
  38.  
  39. extern BitSetRep*   BitSetalloc(BitSetRep*, const unsigned short*, 
  40.                                 int, int, int);
  41. extern BitSetRep*   BitSetcopy(BitSetRep*, const BitSetRep*);
  42. extern BitSetRep*   BitSetresize(BitSetRep*, int);
  43. extern BitSetRep*   BitSetop(const BitSetRep*, const BitSetRep*, 
  44.                              BitSetRep*, char);
  45. extern BitSetRep*   BitSetcmpl(const BitSetRep*, BitSetRep*);
  46.  
  47.  
  48. extern BitSetRep    _nilBitSetRep;
  49.  
  50. class BitSet;
  51.  
  52. class BitSetBit
  53. {
  54. protected:
  55.   BitSet*            src;
  56.   unsigned long      pos;
  57.  
  58.  public:
  59.                      BitSetBit(BitSet* v, int p);
  60.                      BitSetBit(const BitSetBit& b);
  61.                     ~BitSetBit();
  62.                      operator int() const;
  63.   int                operator = (int b);
  64.   int                operator = (const BitSetBit& b);
  65. };
  66.  
  67. class BitSet
  68. {
  69. protected:
  70.   BitSetRep*          rep;
  71.  
  72.   
  73. public:
  74.  
  75. // constructors
  76.                      BitSet();
  77.                      BitSet(const BitSet&);
  78.  
  79.                     ~BitSet();
  80.  
  81.   BitSet&            operator =  (const BitSet& y);
  82.  
  83. // equality & subset tests
  84.  
  85.   friend int         operator == (const BitSet& x, const BitSet& y);
  86.   friend int         operator != (const BitSet& x, const BitSet& y);
  87.   friend int         operator <  (const BitSet& x, const BitSet& y);
  88.   friend int         operator <= (const BitSet& x, const BitSet& y);
  89.   friend int         operator >  (const BitSet& x, const BitSet& y);
  90.   friend int         operator >= (const BitSet& x, const BitSet& y);
  91.  
  92.  
  93. // operations on self
  94.  
  95.   BitSet&            operator |= (const BitSet& y);
  96.   BitSet&            operator &= (const BitSet& y);
  97.   BitSet&            operator -= (const BitSet& y);
  98.   BitSet&            operator ^= (const BitSet& y);
  99.  
  100.   void               complement();
  101.  
  102. // individual bit manipulation
  103.  
  104.   void               set(int pos);
  105.   void               set(int from, int to);
  106.   void               set(); // set all
  107.  
  108.   void               clear(int pos);
  109.   void               clear(int from, int to);
  110.   void               clear(); // clear all
  111.  
  112.   void               invert(int pos);
  113.   void               invert(int from, int to);
  114.  
  115.   int                test(int pos) const;
  116.   int                test(int from, int to) const;
  117.  
  118.   BitSetBit          operator [] (int i);
  119.   
  120. // iterators
  121.  
  122.   int                first(int b = 1) const;
  123.   int                last(int b = 1) const;
  124.  
  125.   int                next(int pos, int b = 1) const;
  126.   int                prev(int pos, int b = 1) const;
  127.   int                previous(int pos, int b = 1) const /* Obsolete synonym */
  128.     { return prev(pos, b); }
  129.  
  130. // status
  131.  
  132.   int                empty() const;
  133.   int                virtual_bit() const;
  134.   int                count(int b = 1) const;
  135.   
  136. // convertors & IO
  137.  
  138.   friend BitSet      atoBitSet(const char* s, 
  139.                                char f='0', char t='1', char star='*');
  140.   // BitSettoa is deprecated; do not use in new programs.
  141.   friend const char* BitSettoa(const BitSet& x, 
  142.                                char f='0', char t='1', char star='*');
  143.  
  144.   friend BitSet      shorttoBitSet(unsigned short w);
  145.   friend BitSet      longtoBitSet(unsigned long w);
  146.  
  147.   friend ostream&    operator << (ostream& s, const BitSet& x);
  148.   void             printon(ostream& s,
  149.                  char f='0', char t='1', char star='*') const;
  150.  
  151. // procedural versions of operators
  152.  
  153.   friend void        and(const BitSet& x, const BitSet& y, BitSet& r);
  154.   friend void        or(const BitSet& x, const BitSet& y, BitSet& r);
  155.   friend void        xor(const BitSet& x, const BitSet& y, BitSet& r);
  156.   friend void        diff(const BitSet& x, const BitSet& y, BitSet& r);
  157.   friend void        complement(const BitSet& x, BitSet& r);
  158.  
  159. // misc
  160.  
  161.   void      error(const char* msg) const;
  162.   int                OK() const;
  163. };
  164.  
  165.  
  166. typedef BitSet BitSetTmp;
  167.  
  168.  
  169.   BitSet      operator |  (const BitSet& x, const BitSet& y);
  170.   BitSet      operator &  (const BitSet& x, const BitSet& y);
  171.   BitSet      operator -  (const BitSet& x, const BitSet& y);
  172.   BitSet      operator ^  (const BitSet& x, const BitSet& y);
  173.  
  174.   BitSet      operator ~  (const BitSet& x);
  175.  
  176. // These are inlined regardless of optimization
  177.  
  178. inline int BitSet_index(int l)
  179. {
  180.   return (unsigned)(l) / BITSETBITS;
  181. }
  182.  
  183. inline int BitSet_pos(int l)
  184. {
  185.   return l & (BITSETBITS - 1);
  186. }
  187.  
  188.  
  189. inline BitSet::BitSet() : rep(&_nilBitSetRep) {}
  190.  
  191. inline BitSet::BitSet(const BitSet& x) :rep(BitSetcopy(0, x.rep)) {}
  192.  
  193. inline BitSet::~BitSet() { if (rep != &_nilBitSetRep) delete rep; }
  194.  
  195. inline BitSet& BitSet::operator =  (const BitSet& y)
  196.   rep = BitSetcopy(rep, y.rep);
  197.   return *this;
  198. }
  199.  
  200. inline int operator != (const BitSet& x, const BitSet& y) { return !(x == y); }
  201.  
  202. inline int operator >  (const BitSet& x, const BitSet& y) { return y < x; }
  203.  
  204. inline int operator >= (const BitSet& x, const BitSet& y) { return y <= x; }
  205.  
  206. inline void and(const BitSet& x, const BitSet& y, BitSet& r)
  207. {
  208.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '&');
  209. }
  210.  
  211. inline void or(const BitSet& x, const BitSet& y, BitSet& r)
  212. {
  213.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '|');
  214. }
  215.  
  216. inline void xor(const BitSet& x, const BitSet& y, BitSet& r)
  217. {
  218.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '^');
  219. }
  220.  
  221. inline void diff(const BitSet& x, const BitSet& y, BitSet& r)
  222. {
  223.   r.rep =  BitSetop(x.rep, y.rep, r.rep, '-');
  224. }
  225.  
  226. inline void complement(const BitSet& x, BitSet& r)
  227. {
  228.   r.rep = BitSetcmpl(x.rep, r.rep);
  229. }
  230.  
  231. #if defined(__GNUG__) && !defined(_G_NO_NRV)
  232.  
  233. inline BitSet operator & (const BitSet& x, const BitSet& y) return r
  234. {
  235.   and(x, y, r);
  236. }
  237.  
  238. inline BitSet operator | (const BitSet& x, const BitSet& y) return r
  239. {
  240.   or(x, y, r);
  241. }
  242.  
  243. inline BitSet operator ^ (const BitSet& x, const BitSet& y) return r
  244. {
  245.   xor(x, y, r);
  246. }
  247.  
  248. inline BitSet operator - (const BitSet& x, const BitSet& y) return r
  249. {
  250.   diff(x, y, r);
  251. }
  252.  
  253. inline BitSet operator ~ (const BitSet& x) return r
  254. {
  255.   ::complement(x, r);
  256. }
  257.  
  258. #else /* NO_NRV */
  259.  
  260. inline BitSet operator & (const BitSet& x, const BitSet& y) 
  261. {
  262.   BitSet r; and(x, y, r); return r;
  263. }
  264.  
  265. inline BitSet operator | (const BitSet& x, const BitSet& y) 
  266. {
  267.   BitSet r; or(x, y, r); return r;
  268. }
  269.  
  270. inline BitSet operator ^ (const BitSet& x, const BitSet& y) 
  271. {
  272.   BitSet r; xor(x, y, r); return r;
  273. }
  274.  
  275. inline BitSet operator - (const BitSet& x, const BitSet& y) 
  276. {
  277.   BitSet r; diff(x, y, r); return r;
  278. }
  279.  
  280. inline BitSet operator ~ (const BitSet& x) 
  281. {
  282.   BitSet r; ::complement(x, r); return r;
  283. }
  284.  
  285. #endif
  286.  
  287. inline BitSet& BitSet::operator &= (const BitSet& y)
  288. {
  289.   and(*this, y, *this);
  290.   return *this;
  291. }
  292.  
  293. inline BitSet& BitSet::operator |= (const BitSet& y)
  294. {
  295.   or(*this, y, *this);
  296.   return *this;
  297. }
  298.  
  299. inline BitSet& BitSet::operator ^= (const BitSet& y)
  300. {
  301.   xor(*this, y, *this);
  302.   return *this;
  303. }
  304.  
  305. inline BitSet& BitSet::operator -= (const BitSet& y)
  306. {
  307.   diff(*this, y, *this);
  308.   return *this;
  309. }
  310.  
  311.  
  312. inline void BitSet::complement()
  313. {
  314.   ::complement(*this, *this);
  315. }
  316.  
  317. inline int BitSet::virtual_bit() const
  318. {
  319.   return rep->virt;
  320. }
  321.  
  322. inline int BitSet::first(int b) const
  323. {
  324.   return next(-1, b);
  325. }
  326.  
  327. inline int BitSet::test(int p) const
  328. {
  329.   if (p < 0) error("Illegal bit index");
  330.   int index = BitSet_index(p);
  331.   return (index >= rep->len)? rep->virt : 
  332.          ((rep->s[index] & (1 << BitSet_pos(p))) != 0);
  333. }
  334.  
  335.  
  336. inline void BitSet::set()
  337. {
  338.   rep = BitSetalloc(rep, 0, 0, 1, 0);
  339. }
  340.  
  341. inline BitSetBit::BitSetBit(const BitSetBit& b) :src(b.src), pos(b.pos) {}
  342.  
  343. inline BitSetBit::BitSetBit(BitSet* v, int p)
  344. {
  345.   src = v;  pos = p;
  346. }
  347.  
  348. inline BitSetBit::~BitSetBit() {}
  349.  
  350. inline BitSetBit::operator int() const
  351. {
  352.   return src->test(pos);
  353. }
  354.  
  355. inline int BitSetBit::operator = (int b)
  356. {
  357.   if (b) src->set(pos); else src->clear(pos); return b;
  358. }
  359.  
  360. inline int BitSetBit::operator = (const BitSetBit& b)
  361. {
  362.   int i = (int)b;
  363.   *this = i;
  364.   return i;
  365. }
  366.  
  367. inline BitSetBit BitSet::operator [] (int i)
  368. {
  369.   if (i < 0) error("illegal bit index");
  370.   return BitSetBit(this, i);
  371. }
  372.  
  373. #endif
  374.